﻿Imports WPFGlue.Framework

Namespace Commanding
    Public Class ActionCommand
        Inherits Command

        Public Shared ReadOnly CanExecuteFuncProperty As DependencyProperty = DependencyProperty.Register("CanExecuteFunc", GetType(Func(Of Boolean)), GetType(ActionCommand))
        Public Property CanExecuteFunc As Func(Of Boolean)
            Get
                Return GetValue(CanExecuteFuncProperty)
            End Get
            Set(ByVal value As Func(Of Boolean))
                SetValue(CanExecuteFuncProperty, value)
            End Set
        End Property

        Protected Overrides ReadOnly Property SupportsCanExecute As Boolean
            Get
                Return (CanExecuteFunc IsNot Nothing)
            End Get
        End Property

        Public Overrides Function CanExecute(ByVal sender As Object, ByVal parameter As Object) As Boolean
            Dim result As Boolean = False
            If (ExecutedAction IsNot Nothing) Then
                If CanExecuteFunc Is Nothing Then
                    result = True
                Else
                    Try
                        result = CanExecuteFunc.Invoke()
                    Catch ex As Exception
                    End Try
                End If
            End If
            Return result
        End Function

        Public Shared ReadOnly ExecutedActionProperty As DependencyProperty = DependencyProperty.Register("ExecutedAction", GetType(Action), GetType(ActionCommand))
        Public Property ExecutedAction As Action
            Get
                Return GetValue(ExecutedActionProperty)
            End Get
            Set(ByVal value As Action)
                SetValue(ExecutedActionProperty, value)
            End Set
        End Property

        Public Overrides Sub Execute(ByVal sender As Object, ByVal parameter As Object)
            If ExecutedAction IsNot Nothing Then
                ExecutedAction.Invoke()
            End If
        End Sub

        Protected Overrides Function CreateInstanceCore() As System.Windows.Freezable
            Return New ActionCommand
        End Function

    End Class

    Public Class ActionCommand(Of T)
        Inherits Command

        Public Shared ReadOnly ExecutedActionProperty As DependencyProperty = DependencyProperty.Register("ExecutedAction", GetType(Action(Of T)), GetType(ActionCommand(Of T)))
        Public Property ExecutedAction As Action(Of T)
            Get
                Return GetValue(ExecutedActionProperty)
            End Get
            Set(ByVal value As Action(Of T))
                SetValue(ExecutedActionProperty, value)
            End Set
        End Property


        Public Shared ReadOnly CanExecuteFuncProperty As DependencyProperty = DependencyProperty.Register("CanExecuteFunc", GetType(Func(Of T, Boolean)), GetType(ActionCommand(Of T)))
        Public Property CanExecuteFunc As Func(Of T, Boolean)
            Get
                Return GetValue(CanExecuteFuncProperty)
            End Get
            Set(ByVal value As Func(Of T, Boolean))
                SetValue(CanExecuteFuncProperty, value)
            End Set
        End Property

        Protected Overrides ReadOnly Property SupportsCanExecute As Boolean
            Get
                Return (CanExecuteFunc IsNot Nothing)
            End Get
        End Property

        Protected Overrides Function CreateInstanceCore() As System.Windows.Freezable
            Return New ActionCommand(Of T)
        End Function

        Public Overrides Sub Execute(ByVal sender As Object, ByVal parameter As Object)
            If ExecutedAction IsNot Nothing Then
                ExecutedAction.Invoke(parameter)
            End If
        End Sub

        Public Overrides Function CanExecute(ByVal sender As Object, ByVal parameter As Object) As Boolean
            Dim result As Boolean = False
            If ExecutedAction IsNot Nothing And TypeOf parameter Is T Then
                If CanExecuteFunc Is Nothing Then
                    result = True
                Else
                    Try
                        result = CanExecuteFunc.Invoke(parameter)
                    Finally
                    End Try
                End If
            End If
            Return result
        End Function

    End Class

    Public Class ActionOfObjectCommand
        Inherits ActionCommand(Of Object)

        Protected Overrides Function CreateInstanceCore() As System.Windows.Freezable
            Return New ActionOfObjectCommand
        End Function
    End Class
End Namespace
